﻿#region License
// Copyright (c) .NET Foundation and contributors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// The latest version of this file can be found at https://github.com/FluentValidation/FluentValidation
#endregion
namespace FluentValidation.AspNetCore {
	using System;
	using System.Collections.Generic;
	using System.Reflection;
	using Internal;
	using Microsoft.AspNetCore.Mvc.ModelBinding.Validation;
	using Resources;
	using Validators;

	internal class EqualToClientValidator : ClientValidatorBase {
		IComparisonValidator EqualValidator => (IComparisonValidator)Validator;

		public EqualToClientValidator(IValidationRule rule, IRuleComponent component) : base(rule, component) {
		}

		public override void AddValidation(ClientModelValidationContext context) {

			var propertyToCompare = EqualValidator.MemberToCompare as PropertyInfo;

			if (propertyToCompare != null) {
				var cfg = context.ActionContext.HttpContext.RequestServices.GetValidatorConfiguration();
				// If propertyToCompare is not null then we're comparing to another property.
				// If propertyToCompare is null then we're either comparing against a literal value, a field or a method call.
				// We only care about property comparisons in this case.

				var comparisonDisplayName =
					cfg.DisplayNameResolver(Rule.TypeToValidate, propertyToCompare, null)
					?? propertyToCompare.Name.SplitPascalCase();

				var formatter = cfg.MessageFormatterFactory()
					.AppendPropertyName(Rule.GetDisplayName(null))
					.AppendArgument("ComparisonValue", comparisonDisplayName);

				string messageTemplate;
				try {
					messageTemplate = Component.GetUnformattedErrorMessage();
				}
				catch (NullReferenceException) {
					messageTemplate = cfg.LanguageManager.GetString("EqualValidator");
				}
				string message = formatter.BuildMessage(messageTemplate);
				MergeAttribute(context.Attributes, "data-val", "true");
				MergeAttribute(context.Attributes, "data-val-equalto", message);
				MergeAttribute(context.Attributes, "data-val-equalto-other", "*." + propertyToCompare.Name);
			}

		}

	}
}
